package threads;

import lombok.Data;

import java.util.concurrent.CountDownLatch;

public class SynchronizedDemo {
    public static void main(String[] args) throws InterruptedException {
        final int TIMES = 10000000;
        System.out.println("start ...");

        T1 t1 = new T1();
        CountDownLatch doneSignal = new CountDownLatch(2);
        new Thread(() -> {
            for (int i = 0; i < TIMES; i++) {
                t1.increment();
            }
            doneSignal.countDown();
            System.out.println("increment finish.");
        }).start();

        new Thread(() -> {
            for (int i = 0; i < TIMES; i++) {
                t1.decrement();
            }
            doneSignal.countDown();
            System.out.println("decrement finish.");
        }).start();

        // wait for all to finish
        doneSignal.await();

        System.out.println(t1.getAmount());
    }
}


/**
 * 在该代码中， increment 、 decrement 锁的是同一个对象，因此这两个方法之间存在互斥性（同一时刻只能有一个线程获取到锁并执行方法）.
 * 即， 线程 A 获取到锁执行 increment() 时， 其他线程执行 decrement() 就获取不到线程的锁。
 */
@Data
class T1 {
    private volatile int amount;

    //隐式锁
    //普通方法上添加 synchronized 锁的是该类的对象实例，相当于 synchronized(this)
    public synchronized void increment() {
        this.amount++;
    }

    public synchronized void decrement() {
        this.amount--;
    }
}


@Data
class T2 {
    private static volatile int instanceCount;

    // 静态方法上添加 synchronized 锁的是 T2.class 对象
    public static synchronized void increment() {
        instanceCount++;
    }

    public static synchronized void decrement() {
        instanceCount--;
    }
}